#ifndef _MY_QUADRATIC_HPP_
#define _MY_QUADRATIC_HPP_

#define quadratic_func QF

#include <iostream>

struct solvers{
    double x;
    double y;
};

class my_quadratic{
    private:
        // 定义二次型结构体
        struct {
            double a;
            double b;
            double c;
        } quadratic_func = {0, 0, 0};
        // 判别式
        int my_delta(){
            double ans = QF.b*QF.b-4*QF.a*QF.c;
            if(ans<0)
                return -1;
            else if(ans == 0)
                return 0;
            else
                return 1;
        }
        // 返回函数值
        inline double func(double x){
            return QF.a*x*x+QF.b*x+QF.c;
        }
        // 二分法, 此时已有func(l)*func(r)<0
        double binary_solve(double l, double r, double epi){
            double mid = 0;
            while(r-l>epi){
                //printf("%.30f %.30f\n",l,r);
                mid = (l+r)/2;
                if(func(mid)==0) return mid;
                else if(func(mid)*func(l)>0)
                    l = mid;
                else r = mid;
            }
            return mid;
        }
        // 二分法求根, 此时默认delta>0, QF.a!=0
        struct solvers solver(){
            double l,r;
            int x;
            struct solvers zeros;
            // 求解左根:
            r = -QF.b/(2*QF.a);
            x = 1;
            while(func(r-x)<0){
                r=r-x;
                x<<=1;
            }
            if(func(r-x)!=0){
                l=r-x;       
                zeros.x = binary_solve(l,r,1e-13);
            }
            else zeros.x = r-x;
            // 求解右根:
            l = -QF.b/(2*QF.a);
            x = 1;
            while(func(l+x)<0){
                l=l+x;
                x<<=1;
            }
            if(func(l+x)!=0){
                r=l+x;
                zeros.y = binary_solve(l,r,1e-13);
            }
            else zeros.y = l+x;
            return zeros;
        }
    public:
        my_quadratic(){
            QF.a = 1;
            QF.b = 0;
            QF.c = -1;
        }
        my_quadratic(double a, double b, double c){
            QF.a = a;
            QF.b = b;
            QF.c = c;
        }
        // 求根
        struct solvers solve(){
            int delta = my_delta();
            struct solvers ans = {0,0};
            if(delta == -1){
                std::cout<<"The Quadratic equation has no real zero!"<<std::endl;
                return ans;
            }
            else if(delta == 0) ans.x = ans.y = -QF.b/(2*QF.a);
            else ans =  solver();
            // 输出误差
            printf("The error: %.6f %.6f\n",func(ans.x),func(ans.y));
            return ans;
        }
};

#endif
